<?php

	namespace Phptricks\system\library\form_validation;

/*
	 * To change this license header, choose License Headers in Project Properties.
	 * To change this template file, choose Tools | Templates
	 * and open the template in the editor.
	 */
	/**
	 * Description of models
	 *
	 * @author Sammy Guergachi <sguergachi at gmail.com>
	 */
	use Phptricks\system\core\library\library;
	use Phptricks\system\library\PhptricksExceptions\PhptricksExceptions as Exc;
	use Phptricks\system\library\loaders\loader as loaders;
	use Phptricks\system\library\request_variables\request_variables as request_variables;
	use Phptricks\system\library\custom_fields\custom_fields as custom_fields;

	class form_validation implements library{

		public $request_variables;
		public $_error = array();
		public $_server = array();
		public $_get = array();
		public $_post = array();
		public $_files = array();
		public $_items = array();
		public $_request = array();
		private $_currentItem = null;
		private $_lang;
		private $_loader;
		public $_array_data;
		public $custom_fields = null;
		private static $_instance = null;

		public function __construct(){
			$this->_loader = loaders::getinstance();
			$this->_lang = $this->_loader->_Language(array('system', 'ar'));
			$this->request_variables = request_variables::getinstance();
			$this->custom_fields = custom_fields::getinstance();
			$this->_post = &$this->request_variables->_post;
			$this->_get = &$this->request_variables->_get;
			$this->_server = &$this->request_variables->_server;
			$this->_request = &$this->request_variables->_request;
			$this->_files = &$this->request_variables->_files;
		}

		public static function &getinstance(){
			if (self::$_instance === null) {
				self::$_instance = new \Phptricks\system\library\form_validation\form_validation();
			}
			return self::$_instance;
		}

		public function _initialize(){
			
		}

		/**
		 * @param Array|String $keys
		 */
		public function post($keys = array()){
			$this->_items = array();
			foreach ($keys as $key => $val) {
				$this->_items[$key] = $val;
				if (isset($this->_post[$key])) {
					$this->_array_data[$key] = &$this->_post[$key];
				} else {
					$this->_array_data[$key] = '';
				}
			}
		}

		/**
		 * @param Array|String $keys
		 */
		public function get($keys = array()){
			$this->_items = array();
			foreach ($keys as $key => $val) {
				$this->_items[$key] = $val;
				if (isset($this->_get[$key])) {
					$this->_array_data[$key] = &$this->_get[$key];
				} else {
					$this->_array_data[$key] = '';
				}
			}
		}

		/**
		 * @param Array|String $vars
		 */
		public function unset_var($vars){
			if (isset($vars) && !empty($vars)) {
				if (is_array($vars)) {
					foreach ($vars as $key) {
						unset($this->_array_data[$key]);
						unset($this->_error[$key]);
					}
				} else {
					unset($this->_array_data[$vars]);
					unset($this->_error[$vars]);
				}
			} else {
				throw new Exc('param $vars not set');
			}
			return true;
		}

		/**
		 * @param Array $param
		 * @param String $var_type post| get
		 * @return boolean
		 */
		public function is_set($param, $var_type = 'post'){
			switch ($var_type) {
				case 'post':
					if (isset($param) && !empty($param)) {
						if (is_array($param)) {
							return in_array($param, $this->_post);
						} elseif (isset($this->_post[$param])) {
							return true;
						} else {
							return false;
						}
					} else {
						throw new Exc('param $param not set');
					}
					break;

				case 'get':
					if (isset($param) && !empty($param)) {
						if (is_array($param)) {
							return in_array($param, $this->_get);
						} elseif (isset($this->_get[$param])) {
							return true;
						} else {
							return false;
						}
					} else {
						throw new Exc('param $param not set');
					}
					break;

				default:
					if (isset($param) && !empty($param)) {
						if (is_array($param)) {
							return in_array($param, $this->_post);
						} elseif (isset($this->_post[$param])) {
							return true;
						}
					} else {
						throw new Exc('param $param not set');
					}
					break;
			}
		}

		public function fetch(){
			foreach ($this->_items as $key => $val) {
				$validation = '';
				if (\preg_match('/\|/iUs', $val)) {
					$validation = explode('|', $val);
				} else {
					$validation = $val;
				}
				$this->_currentItem = $key;
				if (!empty($validation)) {
					$this->_validation_data($this->_post[$key], $validation);
				}
			}
		}

		public function _validation_data($data, $validation){
			try {
				if (is_array($validation) && count($validation) > 0) {
					foreach ($validation as $key => $val) {

						if (!empty($val) && preg_match('/\:/iUs', $val)) {
							$pream = explode(':', $val);
							$function = $pream[0];
							if (!\method_exists($this, $function)) {
								$this->_call($function, $pream);
							} else {
								call_user_func(array($this, $function), $data, $pream[1]);
							}
						} else {
							if (!\method_exists($this, $val)) {
								$this->_call($val, $data);
							} else {
								call_user_func(array($this, $val), $data);
							}
						}
					}
				} else {
					if (!empty($validation)) {
						if (!empty($validation) && preg_match('/\:/iUs', $validation)) {
							$pream = explode(':', $validation);
							$function = $pream[0];

							if (!\method_exists($this, $function)) {
								$this->_call($function, $pream);
							} else {
								call_user_func(array($this, $function), $data, $pream[1]);
							}
						} else {
							if (!\method_exists($this, $val)) {
								$this->_call($val, $data);
							} else {
								call_user_func(array($this, $validation), $data);
							}
						}
					}
				}
			} catch (\Exception $exc) {
				throw new Exc($exc->getTraceAsString());
			}
		}

		public function submit(){
			if (count($this->_error) > 0) {
				$array_return = array();
				$array_return[] = $this->_lang['error_list'];
				foreach ($this->_error as $key => $value) {
					if (\is_array($value)) {
						$value = implode(' , ', $value);
					}
					if (isset($this->_lang[$key])) {
						$array_return[] = $this->_lang[$key] . " : " . $value;
					} else {
						$array_return[] = $key . " : " . $value;
					}
				}
				$this->_error = $array_return;
				return false;
			} else {
				return true;
			}
		}

		private function _call($function = '', $pream = ''){
			if (!empty($function) && \function_exists($function)) {
				if (\is_array($pream)) {
					$pream = \array_merge($this->_post[$this->_currentItem], $pream);
				}
				$datanew = call_user_func($function, $pream);
				$this->_post[$this->_currentItem] = $datanew;
			}
		}

		public function jsonencode(){
			if (isset($this->_post[$this->_currentItem]) && !empty($this->_post[$this->_currentItem])) {
				$this->_post[$this->_currentItem] = $this->custom_fields->encode($this->_post[$this->_currentItem]);
			} else {
				$this->_post[$this->_currentItem] = '';
			}
		}

		public function md5val(){
			$this->_post[$this->_currentItem] = md5($this->_post[$this->_currentItem]);
		}

		public function encode_date($key){
			$encode = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $this->_post[$this->_currentItem], MCRYPT_MODE_CBC, md5(md5($key))));
			$this->_post[$this->_currentItem] = $encode;
		}

		public function decode_date($key){
			$decode = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($this->_post[$this->_currentItem]), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
			$this->_post[$this->_currentItem] = $decode;
		}

		public function minlength($data, $arg){
			if (mb_strlen($data) < $arg) {
				$this->_error[$this->_currentItem][] = sprintf($this->_lang['error_minlength'], $arg);
			}
		}

		public function maxlength($data, $arg){
			if (mb_strlen($data) > $arg) {
				$this->_error[$this->_currentItem][] = sprintf($this->_lang['error_maxlength'], $arg);
			}
		}

		public function length($data, $arg){
			$length = mb_strlen($data);
			if ($length == $arg) {
				$this->_error[$this->_currentItem][] = sprintf($this->_lang['error_length'], $arg, $length);
			}
		}

		public function digit($data){
			if (\preg_match('/^([0-9]+)$/iUs', $data) == false) {
				$this->_error[$this->_currentItem][] = $this->_lang['error_digit'];
			}
		}

		public function checkmail($data){
			if (preg_match('/^([a-zA-Z0-9\_\-\.]+)\@([a-zA-Z0-9\-]+)\.([a-zA-Z]+)$/iUs', trim($data)) == false) {
				$this->_error[$this->_currentItem][] = $this->_lang['error_email'];
			}
		}

		public function arabicval($data){
			$array_char = '/\ذ|\ض|\ص|\ث|\ق|\ف|\غ|\ع|\ه|\خ|\ح|\ج|\د|\ش|\س|\ي|\ب|\ل|\ا|\ت|\ن|\م|\ك|\ط|\ئ|\ء|\ؤ|\ر|\لا|\ى|\ة|\و|\ز|\ظ|\إ|\لأ|\لإ|\آ|\لآ/iUs';
			if (preg_match($array_char, $data) == false) {
				$this->_error[$this->_currentItem][] = $this->_lang['errorabic'];
			}
		}

		public function isnull($data){
			if (is_array($data)) {
				if (count($data) <= 0) {
					$this->_error[$this->_currentItem][] = $this->_lang['error_empty_data'];
				}
			} else if ($data == '') {
				$this->_error[$this->_currentItem][] = $this->_lang['error_empty_data'];
			}
		}

		public function is_array($data){
			if (!is_array($data)) {
				$this->_error[$this->_currentItem][] = $this->_lang['error_not_array'];
			}
		}

		public function matches($data, $other_data){
			if (trim($data) != trim($other_data)) {
				$this->_error[$this->_currentItem][] = $this->_lang['error_matches'];
			}
		}

	}
	